#include <string>

#include "monad.hpp"

// ================== 示例用法 ==================

int main()
{
    // 定义环境配置
    struct Environment
    {
        int multiplier;
        std::string baseMessage;
    } env{2, "Hello"};

    // 示例1: 基础操作组合
    auto computation1 = ask<Environment, std::string, int>().flatMap(
        [](const Environment& env)
        {
            return get<Environment, std::string, int>().flatMap(
                [env](int state)
                {
                    int newValue = env.multiplier * state;
                    return tell<Environment, std::string, int>("Calculated: " + std::to_string(newValue))
                .flatMap([newValue](Unit) {  // 接受 Unit 参数
                    return put<Environment, std::string, int>(newValue);
                })
                .flatMap([newValue](Unit) {  // 接受 Unit 参数
                    return pure<Environment, std::string, int, int>(newValue);
                });
                });
        });

    auto result1 = computation1.run(env, 3);
    printResult("Computation 1", result1);

    // 示例2: 使用 modify 和链式调用
    auto computation2 = pure<Environment, std::string, int, int>(5).flatMap(
        [](int x)
        {
            return modify<Environment, std::string, int>([x](int s) { return s + x; })
            .flatMap([](Unit) {  // 接受 Unit 参数
                return get<Environment, std::string, int>();
            })
            .flatMap([](int newState) {
                return tell<Environment, std::string, int>("State is now: " + std::to_string(newState))
                .flatMap([newState](Unit) {  // 接受 Unit 参数
                    return pure<Environment, std::string, int, int>(newState);
                });
            });
        });

    auto result2 = computation2.run(env, 10);
    printResult("Computation 2", result2);

    // 示例3: 复杂工作流
    auto workflow = ask<Environment, std::string, int>().flatMap(
        [](const Environment& env)
        {
            return tell<Environment, std::string, int>("Starting with: " + env.baseMessage)
            .flatMap([](Unit) {  // 接受 Unit 参数
                return get<Environment, std::string, int>();
            })
            .flatMap([env](int count) {
                int newCount = count + 1;
                return put<Environment, std::string, int>(newCount)
                .flatMap([](Unit) {  // 接受 Unit 参数
                    return tell<Environment, std::string, int>("Incremented counter");
                })
                .flatMap([env, newCount](Unit) {  // 接受 Unit 参数
                    return pure<Environment, std::string, int, std::string>(
                        env.baseMessage + " count: " + std::to_string(newCount));
                });
            });
        });

    auto result3 = workflow.run(env, 0);
    printResult("Workflow", result3);

    return 0;
}